Skip to content

Detect file renames in review diffs#3916

Open
jakeleventhal wants to merge 5 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/detect-file-renames
Open

Detect file renames in review diffs#3916
jakeleventhal wants to merge 5 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/detect-file-renames

Conversation

@jakeleventhal

@jakeleventhal jakeleventhal commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Verification

1. File rename with no changes

Git detects one rename and the viewer renders a single exact-original.ts → exact-renamed.ts entry with -0 +0 and no content hunk.

Exact file rename with no content changes

2. File rename with minimal changes

Git detects an 84% similar rename, so the viewer keeps one minimal-original.ts → minimal-renamed.ts entry and renders the -1 +1 content diff.

File rename with a minimal content diff

3. File rename with too many changes

The files are below Git's rename-similarity threshold, so the viewer correctly renders replaced-new.ts as an addition and replaced-original.ts as a deletion.

Files below the rename threshold shown separately as added and deleted

Summary

  • enable Git rename detection for working-tree and branch review diffs
  • include untracked rename destinations through an isolated temporary index without modifying the user's real index
  • preserve content hunks when a renamed file also has minor edits

Root cause

Working-tree previews generated tracked and untracked patches separately. A normal filesystem rename therefore appeared as an unrelated deletion and addition because Git never saw both paths in the same comparison.

Impact

The diff viewer now renders qualifying file moves as one renamed file while still showing any content changes. Branch comparisons use the same explicit Git rename detection.

Validation

  • pnpm exec vp test apps/server/src/vcs/GitVcsDriverCore.test.ts (27 tests)
  • pnpm exec vp check
  • pnpm exec vp run typecheck
  • git diff --check

Note

Detect file renames in working-tree and branch-range review diffs

  • Replaces the two-step working-tree diff (tracked HEAD diff + separate git diff --no-index per untracked file) with a single unified diff via the new readWorkingTreeReviewDiff function in GitVcsDriverCore.ts.
  • The new function builds a temporary Git index, stages intent-to-add for untracked files, and runs a single patch diff with --find-renames and --minimal against HEAD (or an empty tree when no commits exist yet).
  • Adds --find-renames to the branch-range diff so committed renames are also detected.
  • Truncation now reflects a single diff operation rather than concatenated outputs.
  • Behavioral Change: untracked files, staged index-only deletions, and renames are now included in the working-tree diff; the previous per-file /dev/null diff approach is removed.

Macroscope summarized 0fc42d5.


Note

Medium Risk
Changes how review diff text is produced for the diff viewer (renames, untracked, empty repos, sparse checkout); behavior is covered by new integration tests but could still differ from the old concatenated diffs in edge cases.

Overview
Review working-tree previews no longer merge a tracked git diff HEAD with per-untracked diff --no-index patches. They now go through readWorkingTreeReviewDiff, which copies the repo index into a temp GIT_INDEX_FILE, runs add --intent-to-add -A, and emits one patch diff with --find-renames against HEAD (or an empty tree when there is no commit yet).

Branch-range previews also pass --find-renames on the baseRef...HEAD diff. Truncation follows that single working-tree command instead of OR-ing separate outputs.

Integration tests cover pre-first-commit untracked/staged files, unstaged and committed renames with edits, sparse-checkout scope, and staged index-only deletions.

Reviewed by Cursor Bugbot for commit 0fc42d5. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cdd79e50-375f-4c69-9f54-95cbb6cb7c4e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 12, 2026
@jakeleventhal
jakeleventhal marked this pull request as ready for review July 12, 2026 17:03
@macroscopeapp

macroscopeapp Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR fundamentally changes how working tree review diffs are computed, replacing per-file untracked diff generation with a temporary index-based approach. This is a significant architectural change to core diff logic that affects the review workflow and warrants human review.

You can customize Macroscope's approvability policy. Learn more.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ac42fc27c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/server/src/vcs/GitVcsDriverCore.ts Outdated
Comment thread apps/server/src/vcs/GitVcsDriverCore.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0fc42d5. Configure here.

cwd,
["add", "--intent-to-add", "-A", "--", "."],
{ env },
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add -A erases index-only changes

High Severity

The readWorkingTreeReviewDiff function's git add --intent-to-add -A command on the temporary index re-adds files that were git rm --cached but still exist in the working tree. This causes the working-tree review diff to incorrectly omit staged deletions and other staged-only index changes.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0fc42d5. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0fc42d53cc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

yield* executeGit(
"GitVcsDriver.readWorkingTreeReviewDiff.add",
cwd,
["add", "--intent-to-add", "-A", "--", "."],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve non-ignored index-only deletions

Here git add -h says -A adds changes from tracked and untracked files and -N records only the fact a path will be added, so this temp-index refresh no longer preserves an existing index-only deletion when the same path remains as a non-ignored untracked file. Fresh evidence beyond the prior ignored-file case: after git rm --cached f without adding f to .gitignore, this command turns the copied index into DA f, and the following git diff HEAD is empty if the file still matches HEAD (or shows a modification if it changed), whereas the real index represents a deletion to be committed; the review preview can therefore miss or misstate files being untracked.

Useful? React with 👍 / 👎.

yield* executeGit(
"GitVcsDriver.readWorkingTreeReviewDiff.add",
cwd,
["add", "--intent-to-add", "-A", "--", "."],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep tracked diffs when untracked repos cannot be added

Because git add -h confirms -A scans untracked files too, this command can fail before the diff is generated for an otherwise valid dirty worktree; for example, an untracked nested Git repository with no commit makes git add --intent-to-add -A -- . exit 128 (does not have a commit checked out). Since the caller converts any readWorkingTreeReviewDiff failure into an empty working-tree preview, the presence of that scratch nested repo hides unrelated tracked modifications that the old tracked git diff HEAD -- path still reported.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant